home *** CD-ROM | disk | FTP | other *** search
- ;* GCSQUISH.ASM
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Borland TASM code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Compact objects by marking them for relocate *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: John Jensen Date: 1985 *
- ;* Revision history: *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
- IDEAL
- %PAGESIZE 60, 132
- MODEL medium
- LOCALS @@
- JUMPS
-
- INCLUDE "scheme.ash"
-
- CODESEG
-
- ;************************************************************************
- ;* Macro Support for List/Flonum Compaction *
- ;* *
- ;* Register usage during "move" phase of this routine: *
- ;* ax - backward chain header (destination page index) *
- ;* cx - word count for block move *
- ;* dx - forward chain header (source page index) *
- ;* [ds:si] - source list cell *
- ;* [es:di] - destination list cell *
- ;************************************************************************
- MACRO sq_fix OBJTYPE, OBJDEF, FREEOBJTYPE, FREEOBJDEF, objpage
- DSTPAGE EQU ax
- SRCPAGE EQU dx
-
- lea bx, [@@revlist] ; Create a reverse order linked list of pages
- mov ax, OBJTYPE
- call reverse C, bx, ax
- cmp DSTPAGE, END_LIST ; is list of pages empty?
- je @@done
-
- ADJPAGE DSTPAGE
- mov SRCPAGE, [objpage] ; load page number of least dense page
- ADJPAGE SRCPAGE
-
- mov si, -(SIZE OBJDEF) ; load source page index
- @@findfree:
- cmp DSTPAGE, SRCPAGE ; another destination page available ?
- je @@done
-
- mov di, DSTPAGE
- mov di, [nextcell+di]
- @@iscellavailable:
- cmp di, END_LIST
- jne @@foundfreecell
- mov di, DSTPAGE
- mov [nextcell+di], END_LIST
- mov DSTPAGE, [@@revlist+di] ; ax <- next page in backward chain
- ADJPAGE DSTPAGE
- jmp @@findfree
-
- @@foundfreecell:
- push ds
- ;************************************************************************
- ;* WARNING: The ds Register Doesn't Point to the Data Segment anymore *
- ;************************************************************************
- mov bx, SRCPAGE ; Compute end of page boundary
- ldpage ds, bx
- mov bx, [ss:psize+bx]
- sub bx, SIZE OBJDEF
- @@finddata:
- add si, SIZE OBJDEF ; point to next cell
- cmp si, bx
- ja @@endofpage
- cmp [(FREEOBJDEF ds:si).tag], FREEOBJTYPE
- je @@finddata
-
- ldpage es, DSTPAGE
- push [(FREEOBJDEF es:di).next]
- REPT (SIZE OBJDEF) shr 1
- movsw
- ENDM
- REPT (SIZE OBJDEF) and 1
- movsb
- ENDM
- sub si, SIZE OBJDEF ; back up the source and dest ptrs
- sub di, SIZE OBJDEF
- mov [(OBJDEF ds:si).ptr.page], al
- mov [(OBJDEF ds:si).ptr.disp], di
- or [(OBJDEF ds:si).gc], GC_BIT
- pop di ; copy next free cell offset into di
- ;************************************************************************
- pop ds
- jmp @@iscellavailable
-
- @@endofpage: ; Follow forward pointer - get next source page
- pop ds
- mov bx, SRCPAGE ; copy forward chain header to bx
- mov SRCPAGE, [pagelink+bx]
- ADJPAGE SRCPAGE
-
- mov si, -(SIZE OBJDEF)
- cmp DSTPAGE, SRCPAGE
- jne @@foundfreecell
-
- mov bx, DSTPAGE ; update next avail cell ptr in dest page
- mov [nextcell+bx], di
- @@done:
- ENDM
-
- ;************************************************************************
- ;* List Cell Compaction *
- ;************************************************************************
- PROC C sq_list USES si di
- LOCAL @@revlist:WORD:NUMPAGES
- sq_fix LISTTYPE, LISTDEF, SPECFREE*2, FREELISTDEF, listpage
- ret
- ENDP
-
- ;************************************************************************
- ;* Flonum Compaction *
- ;************************************************************************
- PROC C sq_flo USES si di
- LOCAL @@revlist:WORD:NUMPAGES
- sq_fix FLOTYPE, FLODEF, FREETYPE, FREEFLODEF, flopage
- ret
- ENDP
-
- ;************************************************************************
- ;* Variable Length Object Compaction *
- ;* *
- ;* Register usage during "move" phase of this routine: *
- ;* ax - backward chain header (destination page index) *
- ;* cx - size of block to move *
- ;* dx - forward chain header (source page index) *
- ;* [ds:si] - source list cell *
- ;* [es:di] - destination list cell *
- ;* *
- ;* Notes: *
- ;* *
- ;* 1. Any object which is less than 6 bytes in length cannot be moved *
- ;* because there's no place to put a forwarding pointer. If a *
- ;* page is encountered with such an object (e.g., a zero length *
- ;* vector) that object, and the remaining objects in that page are *
- ;* not copied. Processing continues with the next source page. *
- ;* *
- ;* 2. The current code block cannot be relocated, since the offset *
- ;* into the current code block is held in register si in most of *
- ;* the code of the Scheme Virtual Machine emulator. Since it is *
- ;* not possible to update this offset, the page containing the *
- ;* current code block is skipped, if encountered during *
- ;* compaction. *
- ;************************************************************************
- PROC C sq_var USES si di, @@type:WORD
- LOCAL @@pagesize:WORD, @@headptr:WORD, @@revlist:WORD:NUMPAGES
- DSTPAGE EQU ax
- SRCPAGE EQU dx
-
- lea bx, [@@revlist] ; Create a reverse order linked list of pages
- call reverse C, bx, [@@type]
- cmp DSTPAGE, END_LIST ; is list of pages empty?
- je @@return
-
- ADJPAGE DSTPAGE ; convert list header to page index value
- mov [@@headptr], DSTPAGE ; save destination list header
-
- mov bx, [@@type]
- mov SRCPAGE, [pagelist+bx] ; load page number of least dense
- ADJPAGE SRCPAGE
- jmp @@nextsourcepage
-
- @@endofpage: ; Follow forward ptr - get next source page
- mov bx, SRCPAGE
- mov SRCPAGE, [pagelink+bx]
- ADJPAGE SRCPAGE
- @@nextsourcepage:
- cmp DSTPAGE, SRCPAGE
- je @@return
- cmp SRCPAGE, [cb_reg.page]
- je @@endofpage
- cmp SRCPAGE, [regs+0f8h.page]; current inline code block?
- je @@endofpage
- xor si, si ; clear source page index
-
- @@finddata: ; object to move from source page?
- push ds
- ;************************************************************************
- ;* WARNING: The ds Register Doesn't Point to the Data Segment anymore *
- ;************************************************************************
- mov bx, SRCPAGE
- ldpage ds, bx
- mov bx, [ss:psize+bx] ; load the page size and
- sub bx, OFFSET (TYPE ANYDEF).data ; compute end of page boundary
- @@finddataloop:
- cmp si, bx ; end of source page?
- jbe @@spaceleftfordata
- pop ds
- jmp @@endofpage
- @@spaceleftfordata:
- cmp [(FREEDEF ds:si).tag], FREETYPE
- jne @@founddata
- add si, [(FREEDEF ds:si).len]
- jmp @@finddataloop
-
- @@founddata:
- mov cx, [(ANYDEF ds:si).len]
- ;************************************************************************
- pop ds
- or cx, cx ; check for small string
- jge @@bigstrdata
- mov cx, OFFSET (TYPE STRDEF).buffer + SIZE POINTER
- @@bigstrdata:
- cmp cx, OFFSET (TYPE ANYDEF).data + SIZE POINTER; is object "too small" to relocate?
- jb @@endofpage
- mov DSTPAGE, [@@headptr] ; load destination page list header
- @@nextfreepage:
- mov bx, DSTPAGE ; initialize pointer to dest page
- ldpage es, bx
- mov bx, [psize+bx] ; page size, adjust for boundary check
- sub bx, OFFSET (TYPE ANYDEF).data
- mov [@@pagesize], bx
- xor di, di
- jmp @@findfreeloop
-
- @@findnextfree:
- cmp [(ANYDEF es:di).len], 0 ; check for small string
- jge @@bigstrfree
- add di, OFFSET (TYPE STRDEF).buffer + SIZE POINTER; add the exact length
- jmp @@findfreeloop
- @@bigstrfree:
- add di, [(ANYDEF es:di).len]
- @@findfreeloop:
- cmp di, [@@pagesize]
- ja @@endoffreepage
- cmp [(ANYDEF es:di).tag], FREETYPE
- jne @@findnextfree
- cmp cx, [(FREEDEF es:di).len] ; compare sizes
- ja @@findnextfree ; too big
- je @@exactsize
- mov bx, [(FREEDEF es:di).len]
- sub bx, cx
- cmp bx, SIZE FREEDEF
- jb @@findnextfree ; no place for a free block
- add di, cx
- mov [(FREEDEF es:di).tag], FREETYPE
- mov [(FREEDEF es:di).len], bx
- sub di, cx
- @@exactsize:
- push ds
- ;************************************************************************
- ;* WARNING: The ds Register Doesn't Point to the Data Segment anymore *
- ;************************************************************************
- ldpage ds, SRCPAGE
- mov bx, cx ; remember number of bytes moved
- shr cx, 1 ; move block by words
- rep movsw
- jnc @@moveeven
- movsb
- @@moveeven:
- sub di, bx ; back up the dest. pointer
- neg bx ; - size
- mov [(ANYDEF ds:si+bx).data.page], al ; store a forwarding pointer
- mov [(ANYDEF ds:si+bx).data.disp], di
- or [(ANYDEF ds:si+bx).gc], GC_BIT ; set GC bit to indicate forward
- ;************************************************************************
- pop ds
- jmp @@finddata
-
- @@endoffreepage:
- mov di, DSTPAGE ; Find next possible destination page
- mov DSTPAGE, [@@revlist+di]
- ADJPAGE DSTPAGE
- cmp DSTPAGE, SRCPAGE ; another destination page available ?
- jne @@nextfreepage
- @@return:
- ret
- ENDP sq_var
-
- ;************************************************************************
- ;* Local Support-- Create Reverse Linked List *
- ;* *
- ;* Purpose: To create a reversed copy of the similar page list for *
- ;* pages of a given type. *
- ;* *
- ;* Calling Sequence: header = reverse(dest_array, type_index) *
- ;* header = header pointer of reversed list. *
- ;* dest_array = array to hold the pointers of the reversed *
- ;* linked list. *
- ;* type_index = type index (type*2) of the page type for *
- ;* which the similar page linked list is *
- ;* to be reversed (e.g., LISTTYPE causes *
- ;* the linked list for list cell pages to *
- ;* be reversed. *
- ;************************************************************************
-
- PROC C reverse USES si, @@array, @@type
- mov bx, [@@array]
- mov si, [@@type]
- mov si, [pagelist+si] ; load list header to appropriate page type
- mov ax, END_LIST
- @@loop:
- cmp si, END_LIST ; end of list?
- je @@return
- mov dx, si
- ADJPAGE si
- mov [bx+si], ax ; reversed array <- prev page number
- mov si, [pagelink+si] ; next page
- mov ax, dx ; prev page number <- current page number
- jmp @@loop
- @@return:
- ret
- ENDP reverse
-
- ;************************************************************************
- ;* Garbage Collection -- Compaction Phase *
- ;************************************************************************
- PROC C gcsquish USES si di
- LOCAL @@pagelist:WORD:NUMPAGES, @@freespace:WORD:NUMPAGES
-
- mov ax, 1 ; display "Garbage Squishing"
- call gc_on C, ax
-
- lea bx, [@@freespace]
- call sum_space C, bx ; determine available space in each page
-
- push ds ; model Small -> ss = ds
- pop es
- mov cx, NUMPAGES ; load page count
- lea di, [@@pagelist]
- xor ax, ax ; initialize page number index
- cld
- @@initpagenum:
- stosw
- add ax, 2 ; increment page index
- loop @@initpagenum
-
- mov cx, NUMTYPES ; reset the similar page type chain headers
- mov ax, END_LIST
- lea di, [pagelist]
- rep stosw
-
- mov dx, DEDPAGES*2 ; Sort list of pages by available size
- @@sortnext:
- mov si, dx
- mov di, [@@pagelist+si]
- mov ax, [@@freespace+di] ; load amount of space in base page
- @@sortmore:
- add si, 2
- mov di, [@@pagelist+si]
- cmp ax, [@@freespace+di] ; has current page less space?
- jbe @@sortok
- mov ax, [@@freespace+di] ; load size of smaller free space
- mov di, dx
- mov cx, [@@pagelist+si] ; exchange base page index
- xchg cx, [@@pagelist+di] ; with current page index
- mov [@@pagelist+si], cx
- @@sortok:
- cmp si, (NUMPAGES-1)*2 ; is inner loop complete?
- jl @@sortmore
- add dx, 2 ; increment outer loop index
- cmp dx, (NUMPAGES-1)*2
- jl @@sortnext
-
- mov di, DEDPAGES*2
- @@similoop: ; Update the similar page type chains
- mov si, [@@pagelist+di]
- test [attrib+si], NOMEMORY
- jnz @@simidone
- mov bx, [WORD ptype+si]
- mov ax, [pagelist+bx]
- mov [pagelink+si], ax
- mov ax, si
- corpage ax
- mov [pagelist+bx], ax
- @@simidone:
- add di, 2
- cmp di, NUMPAGES*2
- jl @@similoop
-
- call sq_list C ; Compact List Cells
- call sq_flo C ; Compact Flonums
- mov ax, BIGTYPE ; Compact Bignums
- call sq_var C, ax
- mov ax, CLOSTYPE ; Compact Closures
- call sq_var C, ax
- mov ax, CODETYPE ; Compact Code Blocks
- call sq_var C, ax
- mov ax, VECTTYPE ; Compact Vectors
- call sq_var C, ax
- mov ax, CONTTYPE ; Compact Continuations
- call sq_var C, ax
- mov ax, SYMBTYPE ; Compact symbols
- call sq_var C, ax
- mov ax, STRTYPE ; Compact strings
- call sq_var C, ax
- mov ax, I86TYPE ; Compact Inline code
- call sq_var C, ax
- call srelocat C ; relocate all pointers
- call togglegc C ; complement the GC (forwarding) bits
- call gcsweep C ; reclaim all freed memory
- call gc_off C
- ret
- ENDP gcsquish
-
- END